package com.syh.jn.scm.infrastructure.repository.impl.supplier.base.upstream;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.infrastructure.repository.AbstractAggregateRepository;
import com.syh.jn.scm.domain.supplier.entity.base.upstream.Upstream;
import com.syh.jn.scm.domain.supplier.entity.base.upstream.UpstreamAddress;
import com.syh.jn.scm.domain.supplier.repository.base.upstream.UpstreamRepository;
import com.syh.jn.scm.dto.supplier.base.upstream.supplier.UpstreamVo;
import com.syh.jn.scm.dto.supplier.base.upstream.supplierAddress.UpstreamAddressVo;
import com.syh.jn.scm.infrastructure.repository.model.base.BusinessEntityAddressModel;
import com.syh.jn.scm.infrastructure.repository.model.base.upstream.UpstreamCategoryModel;
import com.syh.jn.scm.infrastructure.repository.model.base.upstream.UpstreamModel;
import com.syh.jn.scm.infrastructure.repository.model.system.AccountModel;
import com.syh.jn.scm.infrastructure.repository.utils.SQLAliasGenerateUtil;
import com.syh.jn.scm.infrastructure.wrapper.BaseResolve;
import com.syh.jn.scm.infrastructure.wrapper.ResolveToSQL;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

@Repository
public class UpstreamRepositoryImpl extends AbstractAggregateRepository<Upstream, UpstreamModel, Long> implements UpstreamRepository {

  /**
   * 增加上游以及上游客户地址
   *
   * @param upstreamSupplier
   * @return
   */
  @Override
  public Long add(Upstream upstreamSupplier) {
    Long id = super.add(upstreamSupplier);
    this.saveAddressesItem(id, upstreamSupplier.getAddressesItem());
    return id;
  }

  /**
   * 修改上游以及上游客户地址
   *
   * @param upstreamSupplier
   */
  @Override
  public void update(Upstream upstreamSupplier) {
    //先删除子项
    this.deleteAddressesItem(upstreamSupplier.getId());
    //添加新的子项
    this.saveAddressesItem(upstreamSupplier.getId(), upstreamSupplier.getAddressesItem());
    //更改主项
    UpstreamModel entityModel = this.hibernateTemplate.get(UpstreamModel.class, upstreamSupplier.getId());
    ExtBeanUtils.copyProperties(upstreamSupplier, entityModel);
  }

  /**
   * 更新报损单状态
   *
   * @param upstreamSupplier
   */
  @Override
  public void updateStatus(Upstream upstreamSupplier) {
    super.update(upstreamSupplier);
  }

  /**
   * 删除上游以及上游客户地址
   *
   * @param upstreamSupplier
   */
  @Override
  public void remove(Upstream upstreamSupplier) {
    this.deleteAddressesItem(upstreamSupplier.getId());
    super.remove(upstreamSupplier);
  }

  @Override
  public List<UpstreamAddressVo> getAddressListById(Long businessEntityId) {
    StringBuffer hql = new StringBuffer();
    hql.append("from BusinessEntityAddressModel model where model.businessEntityId = ? and model.terminalType = 'UPSTREAM' ");
    List<BusinessEntityAddressModel> upstreamAddressModelList = (List<BusinessEntityAddressModel>) this.hibernateTemplate.find(hql.toString(), businessEntityId);
    if (upstreamAddressModelList.isEmpty()) {
      return Collections.emptyList();
    }
    return this.transAddressForm(upstreamAddressModelList);
  }

  /**
   * 保存子项
   *
   * @param id
   * @param upstreamAddressList
   */
  private void saveAddressesItem(Long id, List<UpstreamAddress> upstreamAddressList) {
    upstreamAddressList.stream().forEach((address) -> {
      BusinessEntityAddressModel model = new BusinessEntityAddressModel();
      ExtBeanUtils.copyProperties(address, model);
      model.setTerminalType("UPSTREAM");
      this.hibernateTemplate.save(model);
      model.setBusinessEntityId(id);
    });
  }

  /**
   * 删除子项
   *
   * @param id
   */
  private void deleteAddressesItem(Long id) {
    StringBuffer hql = new StringBuffer();
    hql.append("from BusinessEntityAddressModel model where model.businessEntityId = ? and model.terminalType = 'UPSTREAM' ");
    List<BusinessEntityAddressModel> upstreamAddressModelList = (List<BusinessEntityAddressModel>) this.hibernateTemplate.find(hql.toString(), id);
    upstreamAddressModelList.stream().forEach((addressMode) -> {
      this.hibernateTemplate.delete(addressMode);
    });
  }

  /**
   * 内部方法  业务模型转LogisticsAddressVo
   *
   * @param entityList
   * @return
   */
  private List<UpstreamAddressVo> transAddressForm(List<BusinessEntityAddressModel> entityList) {
    List<UpstreamAddressVo> voList = new ArrayList<>();
    entityList.stream().forEach((entity) -> {
      UpstreamAddressVo vo = new UpstreamAddressVo();
      ExtBeanUtils.copyProperties(entity, vo);
      voList.add(vo);
    });
    return voList;
  }

  @Override
  protected SQL getViewSql() {
    return new SQL() {{
      SELECT(SQLAliasGenerateUtil.aliasGenerate(UpstreamModel.class, "be1", null, new String[]{"categoryName"}),
              "cate1.name as categoryName",
              "account.ID AS accountId",
              "account.LOGIN_ACCOUNT AS account");

      FROM(getModelTableName(UpstreamModel.class) + " be1 ");
      LEFT_OUTER_JOIN(getModelTableName(UpstreamCategoryModel.class) + " cate1 on be1.CATEGORY_ID = cate1.ID");
      LEFT_OUTER_JOIN(getModelTableName(AccountModel.class) + " account on be1.ID = account.BUSINESS_ENTITY_ID and account.TERMINAL_TYPE = 'UPSTREAM' and account.ADMIN = 1 and account.ROLE_ID = 0");
    }};
  }

  @Override
  protected BaseResolve getViewWrapperResolve(Wrapper wrapper) {
    HashMap<String, String> weMap = new HashMap<>();
    weMap.put("id", "be1.ID");
    weMap.put("terminalType", "be1.TERMINAL_TYPE");
    weMap.put("name", "be1.NAME");
    weMap.put("registrationCode", "be1.REGISTRATION_CODE");
    weMap.put("status", "be1.STATUS");
    weMap.put("businessEntityId", "cate1.BUSINESS_ENTITY_ID");
    ResolveToSQL parse = new ResolveToSQL(wrapper, (propertyName) -> {
      return weMap.get(propertyName);
    });
    return parse;
  }

  @Override
  protected Class getViewObject() {
    return UpstreamVo.class;
  }

}
